/*
 * Copyright (C) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file accessibility_espeak_player.h
 * @brief 针对espeak tts引擎实现的无障碍播放器。由于espeak合成语音的逻辑与flite不同，因此需要单独实现。  
 * @brief Play函数提供给espeak回调函数SynthCallback使用，每次espeak_Synth合成之前需调用Interrupt()重置播放状态。
 * @brief 单次espeak_Synth合成的过程中，espeak会多次调用SynthCallback。
 */

#ifndef ACCESSIBILITY_ESPEAK_PLAYER_H
#define ACCESSIBILITY_ESPEAK_PLAYER_H

#include "singleton.h"
#include "audio_renderer.h" //AudioRenderer
#include "speak_lib.h" //espeak
#include <vector>
#include <thread>  
#include <mutex>  
#include <condition_variable>  
#include <atomic>

#define SAMPLE_BUFFER_CAPACITY 144000
#define SINGLE_WRITE_BYTES 4096

namespace OHOS {
namespace Accessibility {

class EspeakPlayer {
    DECLARE_SINGLETON(EspeakPlayer)
public:
    /**
     * @Description: 初始化EspeakPlayer
     */
    bool Init();
    /**
     * @Description: 释放EspeakPlayer  
     */
    bool Release();

    bool Start();
    bool Pause();
    bool Stop();
    bool Drain();
    bool Flush();
    bool SetParams(int32_t channels, int32_t sampleRate);
    /**
     * @Description: 对外播放接口
     * @param: short *wav
     * @Return: bool
     */
    bool Play(short *wav, int numsamples);
    /**
     * @Description: 中断播放，清空缓冲区
     * @Return: bool
     */
    void Interrupt();

private:
    /**
     * @Description: 向sampleBuffer_中写入数据，同时设置audio参数，之后唤醒playThread_
     * @Param: short *wav
     * @Return: bool
     */
    bool WriteToBuffer(short *wav, int numsamples);

    /**
     * @Description: 后台播放线程函数，循环写入sampleBuffer_中的数据
     * @Return: void
     */
    void PlayBackThread();

    /**
     * @Description: 从sampleBuffer_中读取数据，写入AudioRenderer
     * @Return: bool
     */
    bool WriteFromBuffer();

    bool WriteFlag();

    std::unique_ptr<AudioStandard::AudioRenderer> renderer_ = nullptr;
    //缓存audiorenderer支持的音频参数
    std::vector<AudioStandard::AudioSamplingRate> supportedSampleList_;
    std::vector<AudioStandard::AudioChannel> supportedChannelsList_;

    std::atomic<bool> bufferFlag_ = false; //作为是否播放的标志
    std::atomic<bool> exitFlag_ = false; //是否退出playThread_
    std::atomic<size_t> bufferSize_ = 0;
    std::atomic<size_t> bufferWritePos_ = 0;
    std::unique_ptr<uint8_t[]> sampleBuffer_;
    std::thread playThread_;
    std::mutex mutex_;
    std::mutex bufferFlagMutex_;
    std::condition_variable cond_;
};


} // namespace Accessibility
} // namespace OHOS

#endif // ACCESSIBILITY_ESPEAK_PLAYER_H